home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 020a / tvg102_s.zip / TVGRAPH.PAS < prev    next >
Pascal/Delphi Source File  |  1991-04-02  |  22KB  |  845 lines

  1.  
  2. {$A-,B-,D+,E+,F+,G-,I+,L+,N-,O-,R-,S-,V-,X-}
  3. {$M 16384,0,655360}
  4. {$DEFINE DEMO}
  5. unit TvGraph;
  6.  
  7. (* Include this unit before any other TVision unit and the program will *)
  8. (* Work entirely in graphics mode and look identical ( although slower) *)
  9. (* to the original text display. Using this in conjunction with a       *)
  10. (* companion unit TVGOBJ, will allow you to do graphics using the full  *)
  11. (* capability of TURBO VISION Menus,Dialog boxes etc.                   *)
  12.  
  13. interface
  14.  
  15. uses
  16.   Drivers,Objects,Views;
  17.  
  18. const
  19.   GraphXMax=10000;
  20.   GraphYMax=07500;
  21.   smEGA = $0010;
  22.   smVGA = $0012;
  23.   smGraphAutoDetect=$00FF;   (* Autodetect *)
  24.   wrmOVERWRITE = 0;
  25.   wrmAND = 1;
  26.   wrmOR = 2;
  27.   wrmXOR = 3;
  28.  
  29. type
  30.  PGRect=^GRect;
  31.  GRect=Trect;
  32.  
  33.  PGPoint=^GPoint;
  34.  GPoint=TPoint;
  35.  
  36. function NextGraphId:byte;
  37. procedure UseGraphId(b:byte);
  38. procedure ReleaseGraphId(b:byte);
  39. procedure TextToGraphics(T:TRect;var G:Grect);
  40. procedure RawDrawLine(X1,Y1,X2,Y2:integer;Color:word);
  41. procedure DrawLine(X1,Y1,X2,Y2:integer;Color:word);
  42. function ISin(X:integer):integer;
  43. function ICos(X:integer):integer;
  44.  
  45. implementation
  46.  
  47. const
  48.   (********************************************************************)
  49.   (*                                                                  *)
  50.   (*    CRITICAL - WARNING LOOK AT THIS CONSTANT - VERSION DEPENDANT  *)
  51.   (*                                                                  *)
  52.   (********************************************************************)
  53.   OfsFromInit=$261-$222;
  54.   (* Offset between where the Views.Tview.Init procedure is and where *)
  55.   (* the code starts for the Checksnow = TRUE code                    *)
  56.   (* This value is absolutely critical and may change between         *)
  57.   (* Turbovision releases  WATCH OUT CRITICAL                         *)
  58.  
  59.   CurrentGraphWindow:byte=1;
  60.   CurrentLineStyle:word=$FFFF;
  61.                         (* Current Line style in 1=line 0=no line       *)
  62.   CurrentLineWriteMode:byte=$00;
  63.                         (* Current Write mode for lines                 *)
  64.   SineTable:array[0..180] of integer=
  65.        (0,9,18,27,36,45,54,63,71,80,89,98,107,116,125,134,143,151,160,169,178,
  66.         187,195,204,213,222,230,239,248,256,265,274,282,291,299,308,316,325,333,
  67.         342,350,359,367,375,384,392,400,408,416,425,433,441,449,457,465,473,481,
  68.         489,496,504,512,520,527,535,543,550,558,565,573,580,587,595,602,609,616,
  69.         623,630,637,644,651,658,665,672,679,685,692,698,705,711,718,724,730,737,
  70.         743,749,755,761,767,773,779,784,790,796,801,807,812,818,823,828,834,839,
  71.         844,849,854,859,864,868,873,878,882,887,891,896,900,904,908,912,916,920,
  72.         924,928,932,935,939,943,946,949,953,956,959,962,965,968,971,974,977,979,
  73.         982,984,987,989,991,994,996,998,1000,1002,1003,1005,1007,1008,1010,1011,
  74.         1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1022,1023,1023,1023,
  75.         1024,1024,1024,1024);
  76.  
  77.  
  78. type
  79. {$IFDEF DEMO}
  80.   Vector = record X1,Y1,X2,Y2:word; end;
  81. {$ENDIF}
  82.   ABitFont = array[0..255] of array[0..15] of byte;
  83.   (* Store upto 32 line high font *)
  84.   PAbitFont = ^ABitFont;
  85.   (* The pointer to a copy of the currently in use font *)
  86.   PtrRec = record O,S:word; end;  (* used to separate Ofs and Seg     *)
  87. var
  88.   (* All the hardware dependant routines called indirectly *)
  89.   Do_INIT_X:procedure;
  90.   Do_DONE_X:Procedure;
  91.   TVGraphCursorOn_X,
  92.   TVGraphCursorOff_X,
  93.   TVUpdateCursor_X,
  94.   Do_GraphMOV_X,
  95.   NewJmp_GraphMOV_X:pointer;
  96.   Draw_Any_Line_X:procedure (X1,Y1,X2,Y2:word;Color:byte);
  97.   Draw_Horiz_Line_X:procedure (X1,X2,Y:word;Color:byte);
  98.   Draw_Vert_Line_X:procedure (X,Y1,Y2:word;Color:byte);
  99.  
  100.   P1,P2:Pointer;        (* General pointers used for copies             *)
  101.   BytesPerLine:word;    (* Bytes per line in graphics mode              *)
  102.   VideoBufferSeg:word;  (* Video Segment for display                    *)
  103.   GTVEventRoutine:PtrRec;
  104.                         (* Address of TVision mouse event handler       *)
  105.   GTVEventMask:word;    (* Mask as passed by call to handler install    *)
  106.   OldINT33h,OldINT10h:Pointer;
  107.                         (* Old pointers to call for INT 33 and INT 10   *)
  108.   Int33h:Pointer absolute $0000:$00CC;
  109.                         (* INT 33h actual address                       *)
  110.   Int10h:Pointer absolute $0000:$0040;
  111.                         (* INT 10h actual address                       *)
  112.   RomFont:PABitFont absolute $0000:$010C;
  113.                         (* Address of current FONT                      *)
  114.   ColorList:word;       (* Pointer to List of color masks in EGA memory *)
  115.   Count:word;           (* Counts down the number of char's in GRAPHMOV *)
  116.   DestOfs:word;         (* Destination in EGA of the current mask       *)
  117.   TextSource:PtrRec;    (* Source for next Ch/Attr pair                 *)
  118.   TextDest:word;        (* Normal destination for text 0..screen size   *)
  119.   SaveJump:word;        (* Save jump location for GraphMov              *)
  120.   TvGraphLoc,TvGraphCursor:word;
  121.                         (* Store current text x,y and top/bottom cursor *)
  122.   GraphMouseLoc:TPoint; (* Graphics location of Mouse *)
  123.   TvViziFlag:byte;      (* Toggles ON=FF and OFF=00 for cursor          *)
  124.   FontTable:ABitFont;   (* In Memory font table                         *)
  125.   PtrFontTable:PABitFont;(* Pointer to In Memory font table             *)
  126.   GraphWriteAvail:array[0..4095] of byte;
  127.   (* one byte for each text position on the screen, 0=text screen and   *)
  128.   (* a number 1-254 representing distinct graphics windows and 255      *)
  129.   (* represents the mouse cursor positions                              *)
  130.   GraphIdSet:set of byte;
  131.   CharWidth,CharHeight:byte;
  132.                         (* Width and Height in text mode                *)
  133.   GraphWidth,GraphHeight:word;
  134.                         (* Width and height in graphics                 *)
  135. {$IFDEF DEMO}
  136.   DWString:array[1..35] of word; (* Used for text writing *)
  137.  
  138. const
  139.   TVGraphAd:array[1..29] of Vector=
  140.   ((X1:220;Y1:125;X2:240;Y2:125), (*T2*)
  141.    (X1:230;Y1:125;X2:230;Y2:150),
  142.    (X1:245;Y1:125;X2:255;Y2:150), (*V2*)
  143.    (X1:255;Y1:150;X2:265;Y2:125),
  144.    (X1:290;Y1:125;X2:280;Y2:125), (*G7*)
  145.    (X1:280;Y1:125;X2:270;Y2:130),
  146.    (X1:270;Y1:130;X2:270;Y2:145),
  147.    (X1:270;Y1:145;X2:280;Y2:150),
  148.    (X1:280;Y1:150;X2:290;Y2:150),
  149.    (X1:290;Y1:150;X2:290;Y2:140),
  150.    (X1:290;Y1:140;X2:280;Y2:140),
  151.    (X1:295;Y1:150;X2:295;Y2:125), (*R6*)
  152.    (X1:295;Y1:125;X2:305;Y2:125),
  153.    (X1:305;Y1:125;X2:315;Y2:130),
  154.    (X1:315;Y1:130;X2:315;Y2:135),
  155.    (X1:315;Y1:135;X2:295;Y2:140),
  156.    (X1:305;Y1:140;X2:315;Y2:150),
  157.    (X1:320;Y1:150;X2:320;Y2:135), (*A5*)
  158.    (X1:320;Y1:135;X2:330;Y2:125),
  159.    (X1:330;Y1:125;X2:340;Y2:135),
  160.    (X1:340;Y1:135;X2:340;Y2:150),
  161.    (X1:320;Y1:140;X2:340;Y2:140),
  162.    (X1:345;Y1:150;X2:345;Y2:125), (*P4*)
  163.    (X1:345;Y1:125;X2:365;Y2:125),
  164.    (X1:365;Y1:125;X2:365;Y2:140),
  165.    (X1:365;Y1:140;X2:345;Y2:140),
  166.    (X1:370;Y1:125;X2:370;Y2:150), (*H3*)
  167.    (X1:390;Y1:125;X2:390;Y2:150),
  168.    (X1:370;Y1:137;X2:390;Y2:137));
  169.   AdvertText:array[1..9] of string[35]=
  170.   ('      Graphics in TURBOVISION      ',
  171.    '         Copyright 1991            ',
  172.    'C.L.Burke of MindWare QLD Australia',
  173.    'R.A.Morris of KHIRON QLD Australia ',
  174.    '         The Wizards of Oz         ',
  175.    '          AND COMING SOON          ',
  176.    '   GWHIZ graphics objects in the   ',
  177.    '      spirit of TurboVision        ',
  178.    '    PRESS ANY KEY TO CONTINUE      ');
  179. {$ENDIF}
  180.  
  181. procedure DisableInterrupts; inline($FA);
  182. procedure EnableInterrupts; inline($FB);
  183.  
  184. procedure MouseCursorOff;assembler;
  185. asm
  186.  mov ax,0002h
  187.  cli
  188.  pushf
  189.  call [OldInt33h]
  190.  sti
  191. end;
  192.  
  193. procedure MouseCursorOn;assembler;
  194. asm
  195.  mov ax,0001h
  196.  cli
  197.  pushf
  198.  call [OldInt33h]
  199.  sti
  200. end;
  201.  
  202. {$I TVGRAPH.IN0}        (* Display Identify routines *)
  203. {$I TVGRAPH.IN1}        (* Display Specific routines *)
  204.  
  205.  
  206. {$IFDEF DEMO}
  207.  
  208. procedure RawWriteString(X,Y:Word;S:String);
  209. const
  210.  NormTextColor=$1A00;
  211. var
  212.  ScrLoc:word;
  213.  Cnt:word;
  214. begin
  215.  ScrLoc:=Y*160+X*2;
  216.  for Cnt:=1 to 35 do
  217.    DWString[Cnt]:=NormTextColor+ord(S[Cnt]);
  218.  asm
  219.   mov si,offset DWString
  220.   mov ax,seg DWString
  221.   mov di,[ScrLoc]
  222.   push ds
  223.   mov ds,ax
  224.   mov cx,35
  225.   call [Do_GraphMOV_X]
  226.   pop ds
  227.  end;
  228. end;
  229.  
  230. procedure Advertisement;
  231. const
  232.  BorderColor=15;
  233.  BackgroundColor=1;
  234.  VectorColor=14;
  235. var
  236.  XL,XH,YL,YH:word;
  237.  Cnt:word;
  238. begin
  239.  for cnt:=0 to 3 do
  240.   RawDrawLine(170-Cnt,100-Cnt,470+Cnt,100-Cnt,BorderColor);
  241.  for cnt:=0 to 3 do
  242.   RawDrawLine(470+Cnt,100-Cnt,470+Cnt,300+Cnt,BorderColor);
  243.  for cnt:=0 to 3 do
  244.   RawDrawLine(470+Cnt,300+Cnt,170-Cnt,300+Cnt,BorderColor);
  245.  for cnt:=0 to 3 do
  246.   RawDrawLine(170-Cnt,300+Cnt,170-Cnt,100-Cnt,BorderColor);
  247.  for Cnt:=101 to 299 do
  248.   RawDrawLine(171,Cnt,469,Cnt,BackGroundColor);
  249.  for Cnt:=1 to 29 do
  250.  With TvGraphAd[Cnt] do
  251.  begin
  252.   RawDrawLine(X1+9,Y1-10,X2+9,Y2-10,VectorColor);
  253.   RawDrawLine(X1+10,Y1-11,X2+10,Y2-11,VectorColor);
  254.   RawDrawLine(X1+10,Y1-10,X2+10,Y2-10,VectorColor);
  255.   RawDrawLine(X1+10,Y1-9,X2+10,Y2-9,VectorColor);
  256.   RawDrawLine(X1+11,Y1-10,X2+11,Y2-10,VectorColor);
  257.  end;
  258.  XL:=(175 div Charwidth)+1;
  259.  XH:=(465 div Charwidth)-1;
  260.  YL:=(140 div CharHeight);
  261.  YH:=(295 div CharHeight)-1;
  262.  for cnt:=1 to 9 do
  263.    RawWriteString(XL+1,YL+cnt,AdvertText[cnt]);
  264.  asm
  265.   mov ax,0
  266.   int 16h
  267.  end;
  268. end;
  269. {$ENDIF}
  270.  
  271. function NextGraphId:byte;
  272. var
  273.  I:byte;
  274.  Found:boolean;
  275. begin
  276.  I:=0;
  277.  repeat
  278.   Inc(I);
  279.   Found:=not (I in GraphIdSet);
  280.  until (I=254) or found;
  281.  NextGraphId:=I;
  282. end;
  283.  
  284. procedure UseGraphId(b:byte);
  285. begin
  286.  GraphIdSet:=GraphIdSet+[b];
  287.  CurrentGraphWindow:=b;
  288. end;
  289.  
  290. procedure ReleaseGraphId(b:byte);
  291. begin
  292.  GraphIdSet:=GraphIdSet-[b];
  293. end;
  294.  
  295. function GraphIdAt(X,Y:integer):byte;
  296. begin
  297.  X:=X div CharWidth;
  298.  Y:=Y div CharHeight;
  299.  GraphIdAt:=GraphWriteAvail[Y*ScreenWidth+X]
  300. end;
  301.  
  302. function ISin(X:integer):integer; assembler;
  303. asm
  304. (* X is number of 16ths of a degree *)
  305.      mov bx,OFFSET SineTable
  306.      mov ch,1         (* sign of result *)
  307.      mov si,[X]
  308.      test si,08000h
  309.      jz @L01
  310.      neg ch           (* negative SIN(-A) = -SIN(A) *)
  311.      neg si           (* Angle is positive *)
  312. @L01:cmp si,16*360
  313.      jl  @L02
  314.      sub si,16*360
  315.      jmp @L01
  316. @L02:cmp si,16*180    (* Angle is 0..359 *)
  317.      jl  @L03
  318.      neg ch
  319.      sub si,16*180    (* angle is 0..180 *)
  320. @L03:cmp si,16*90
  321.      jle @L04
  322.      neg si
  323.      add si,16*180
  324. @L04:mov cl,3         (* angle is 0..90 *)
  325.      shr si,cl
  326.      shl si,1
  327.      mov ax,[BX+SI]
  328.      test ch,080h
  329.      jz @L05
  330.      neg ax
  331. @L05:
  332. end;
  333.  
  334. function ICos(X:integer):integer;
  335. begin
  336.  ICos:=ISin(X+90*16);
  337. end;
  338.  
  339. procedure ClearWindow(Bounds:TRect;Color:word);
  340. var
  341.  Cnt:word;
  342. begin
  343.  for Cnt:=Bounds.A.Y to Bounds.B.Y do
  344.    RawDrawLine(Bounds.A.X,Cnt,Bounds.B.X,Cnt,Color);
  345. end;
  346.  
  347. procedure New_INT10h; assembler;
  348. asm
  349. (* Replace INT10 to emulate cursor stuff *)
  350.  push ds
  351.  pushf
  352.  
  353.  push si
  354.  mov si,seg @Data
  355.  mov ds,si
  356.  pop si
  357.  
  358.  cmp ah,1
  359.  jne @NOT1
  360.  call [TvGraphCursorOff_X]
  361.  test cx,0E0E0h
  362.  jnz @NoTrans
  363.  push ax
  364.  mov ah,[CharHeight]
  365.  dec ah                 (* AH= max cursor line *)
  366.  sub ah,cl              (* Difference between max line and request e.g. -2*)
  367.  cmp cl,7
  368.  jle @CL_OK
  369.  add cl,ah
  370. @CL_OK:
  371.  cmp ch,7
  372.  jle @CH_OK
  373.  add ch,ah
  374. @CH_OK:
  375.  pop ax
  376. @NoTrans:
  377.  mov [TvGraphCursor],cx
  378.  call [TvUpdateCursor_X]
  379.  jmp @DOIRET
  380. @NOT1:
  381.  cmp ah,2
  382.  jne @NOT2
  383.  call [TvGraphCursorOff_X]
  384.  mov [TvGraphLoc],dx
  385.  call [TvUpdateCursor_X]
  386.  jmp @DOIRET
  387. @NOT2:
  388.  cmp ah,3
  389.  jne @NOT3
  390.  mov dx,[TvGraphLoc]
  391.  mov cx,[TvGraphCursor]
  392.  jmp @DOIRET
  393. @NOT3:
  394.  call [OldInt10h]
  395.  pop ds
  396.  iret
  397. @DOIRET:
  398.  popf
  399.  pop ds
  400.  iret
  401. end;
  402.  
  403. procedure New_EventHandler;assembler;
  404. asm
  405. (* Old event handler divides mouse co-ordinates by 8 all the time   *)
  406. (* New Event handler which multiplies by 8 and divides by character *)
  407. (* and then calls the old event handler resulting in the correct    *)
  408. (* division.                                                        *)
  409.     push si
  410.     push ax
  411.     push bx
  412.     mov si,seg @Data
  413.     mov ds,si
  414.  
  415.     mov [GraphMouseLoc.X],cx
  416.     mov [GraphMouseLoc.Y],dx
  417.  
  418.     mov ax,8
  419.     mul dx             (* DX:AX = 8*Y *)
  420.     xor bh,bh
  421.     mov bl,[CharHeight]
  422.     div bx          (* DX:AX = 8*Y/CharHeight *)
  423.     mov dx,ax          (* DX = 8*Y/CharHeight *)
  424.  
  425.     push dx
  426.  
  427.     mov ax,8       (* X co-ord *)
  428.     mul cx         (* AX = X*8 *)
  429.     xor bh,bh
  430.     mov bl,[CharWidth]
  431.     div bx         (* AX = X*8/CharWidth *)
  432.     mov cx,ax      (* X <- X*8/CharWidth *)
  433.  
  434.     pop dx
  435.  
  436.     pop bx
  437.     pop ax
  438.     pop si
  439.     jmp dword [GTVEventRoutine]
  440. end;
  441.  
  442. procedure New_INT33h; assembler;
  443. (* New mouse interrupt handler to fix graphics *)
  444. asm
  445.  cli
  446.  push ds
  447.  pushf                        (* call interrupt will call as INT 33h *)
  448.  push ax
  449.  mov ax,seg @Data
  450.  mov ds,ax
  451.  pop ax
  452.  cmp ax,0ch
  453.  jz  @change1
  454.  call [OldInt33h]
  455.  pop ds
  456.  sti
  457.  iret
  458.  
  459. @Change1:   (* Intercept the change Event routine and save the values *)
  460.  mov [GTVEventMask],CX
  461.  mov cx,es
  462.  mov [GTVEventRoutine.S],Cx
  463.  mov [GTVEventRoutine.O],Dx
  464.  mov CX,[GTVEventMask]
  465.  mov dx,SEG New_EventHandler  (*our Event handler *)
  466.  mov es,dx
  467.  mov dx,OFFSET New_EventHandler
  468.  call [OldInt33h] (* has been intercepted *)
  469.  
  470.  pop ds
  471.  sti
  472.  iret
  473. end;
  474.  
  475. (* Turn off Events *)
  476. procedure ResetMouse; assembler;
  477. asm
  478.  mov ax,0
  479.  int 33h
  480.  ret
  481. end;
  482.  
  483. (* Normal text mode video routines *)
  484. procedure SetVidParams(var Smode,Cline:word);
  485. begin
  486.   asm
  487.     les bx,Smode
  488.     mov ax,es:[bx]
  489.     mov ah,0
  490.     int 10h
  491.     mov ah,1
  492.     les bx,Cline
  493.     mov cx,es:[bx]
  494.     int 10h
  495.   end;
  496. end;
  497.  
  498. procedure GetVidParams(var Smode,Cline:word);
  499. begin
  500.   asm
  501.     mov ah,0fh          (* Save video mode *)
  502.     int 10h
  503.     mov ah,0
  504.     les bx,Smode
  505.     mov es:[bx],ax
  506.     mov ah,03h
  507.     int 10h
  508.     les bx,Cline
  509.     mov es:[bx],cx
  510.   end;
  511. end;
  512.  
  513. (* Copy ROM font table to RAM *)
  514. procedure CopyROMfont;
  515. var
  516.   FontPtr:pointer;
  517.   Cnt:byte;
  518. begin
  519.   FontPtr:=RomFont;
  520.   for cnt:=0 to 255 do
  521.   begin
  522.    move(FontPtr^,FontTable[cnt],CharHeight); (* Insert New Jump for GRAPH_MOV *)
  523.    inc(longint(FontPtr),CharHeight);
  524.   end;
  525.   PtrFontTable:=@FontTable;
  526. end;
  527.  
  528. (* This function replaces the DoneVideo procedure command in Drivers *)
  529. procedure Do_DoneVideo;
  530. var
  531.  CLine,SMode:word;
  532. begin
  533.  Do_DONE_X;
  534.  DisableInterrupts;
  535.  Int33h:=OldInt33h;
  536.  Int10h:=OldInt10h;
  537.  EnableInterrupts;
  538.  SetVidParams(StartupMode,CursorLines);
  539. end;
  540.  
  541. (* This code is copied over start of the DoneVideo procedure in Drivers *)
  542. procedure NewJmp_DoneVideo; assembler;
  543. asm
  544.  jmp far ptr Do_DoneVideo (* 5 *)
  545. end;                    (*TOTAL 5 bytes*)
  546.  
  547. (* This function replaces the SetVideoMode procedure command in Drivers *)
  548. procedure Do_SetVideoMode(Mode:word);
  549. var
  550.   Driver:Vsystem;
  551. begin
  552.   Driver := WhatVsystem;
  553.   if hi(Mode)=$01 then HiresScreen:=TRUE;
  554.   Mode:=Mode and $FF;
  555.   if (Mode>$13) or
  556.     not (Driver in GraphScreenInfo[Mode].SuitableAdapters) or
  557.     (GraphScreenInfo[Mode].ScreenSeg= $0000) then
  558.    begin
  559.      case Driver of
  560.        Mono,Herc:Mode:=smMono;
  561.        EGA:Mode:=smEGA;
  562.        VGA:Mode:=smVGA;
  563.        else Mode:=smCO80;
  564.      end;
  565.    end;
  566.   if GraphScreenInfo[Mode].ScreenWriteType=_GRAPHICS then
  567.   begin
  568.     case Mode of
  569.       smEGA:Do_Set_EGAVGA;
  570.       smVGA:Do_Set_EGAVGA;
  571.     end;
  572.     ScreenMode:=Mode;
  573.     SetVidParams(ScreenMode,CursorLines);
  574.     P1:=@Views.Tview.Init;
  575.     dec(PtrRec(P1).O,OfsFromInit);
  576.     P2:=NewJmp_GraphMOV_X;
  577.     move(P2^,P1^,13); (* Insert New Jump for GRAPH_MOV *)
  578.     HiresScreen:=FALSE;
  579.     CharWidth:=8;
  580.     CharHeight:=Mem[$40:$85];
  581.     ScreenWidth:=GraphScreenInfo[Mode].Xres div CharWidth;
  582.     ScreenHeight:=GraphScreenInfo[Mode].YRes div CharHeight;
  583.     GraphWidth:=GraphScreenInfo[Mode].Xres;
  584.     GraphHeight:=GraphScreenInfo[Mode].YRes;
  585.     CheckSnow:=TRUE;
  586.     BytesPerLine:= ScreenWidth;
  587.     VideoBufferSeg:=GraphScreenInfo[Mode].ScreenSeg;
  588.     TvViziFlag:=0;
  589.     TvGraphLoc:=0;
  590.     TvGraphCursor:=$2000;
  591.     asm
  592.       call [TvUpdateCursor_X];
  593.     end;
  594.     ScreenBuffer:=Ptr(GraphScreenInfo[Mode].ScreenSeg,$0000);
  595.     Do_INIT_X;
  596.   end else
  597.   begin
  598.     Do_DONE_X;
  599.     SetVidParams(StartupMode,CursorLines);
  600.     writeln('That mode not supported in TVGRAPH yet ');
  601.     writeln;
  602.     halt(255);
  603.   end;
  604. end;
  605.  
  606. (* This code is copied over start of the SetVideoMode procedure in Drivers *)
  607. procedure NewJmp_SetVideoMode; assembler;
  608. asm
  609.  jmp far ptr Do_SetVideoMode (* 5 *)
  610. end;                    (*TOTAL 5 bytes*)
  611.  
  612.  
  613. (* This function replaces the InitVideo procedure command in Drivers *)
  614. procedure Do_InitVideo;
  615. begin
  616.   ResetMouse;
  617.   GetVidParams(StartupMode,CursorLines);
  618.   Do_SetVideoMode(smGraphAutoDetect);
  619. {  Do_SetVideoMode(smEGA);}
  620.   DisableInterrupts;
  621.   OldInt33h:=Int33h;
  622.   OldInt10h:=Int10h;
  623.   Int33h:=@New_Int33h;
  624.   Int10h:=@New_Int10h;
  625.   EnableInterrupts;
  626.   CopyROMFont;
  627. {$IFDEF DEMO}
  628.   fillchar(GraphWriteAvail,sizeof(GraphWriteAvail),#1);
  629.   AdVertisement;
  630. {$ENDIF}
  631.   fillchar(GraphWriteAvail,sizeof(GraphWriteAvail),#0);
  632. end;
  633.  
  634. (* This code is copied over start of the InitVideo procedure in Drivers *)
  635. procedure NewJmp_InitVideo; assembler;
  636. asm
  637.  jmp far ptr Do_InitVideo (* 5 *)
  638. end;                    (*TOTAL 5 bytes*)
  639.  
  640. function RegionOf(X,Y:integer;WX1,WY1,WX2,WY2:integer):byte; assembler;
  641. asm
  642.  xor ch,ch
  643.  mov ax,[X]
  644.  
  645.  cmp ax,[WX1]
  646.  jge @RO1
  647.  or ch,0001B
  648. @RO1:
  649.  cmp ax,[WX2]
  650.  jle @RO2
  651.  or ch,0100B
  652. @RO2:
  653.  mov ax,[Y]
  654.  cmp ax,[WY1]
  655.  jge @RO3
  656.  or ch,0010B
  657. @RO3:
  658.  cmp ax,[WY2]
  659.  jle @RO4
  660.  or ch,1000B
  661. @RO4:
  662.  mov al,ch
  663. end;
  664.  
  665.  
  666. procedure SwapInts(var A,B:integer);assembler;
  667. asm
  668.  push ds
  669.  les si,A
  670.  lds di,B
  671.  mov ax,es:[si]
  672.  xchg ax,[di]
  673.  mov es:[si],ax
  674.  pop ds
  675. end;
  676.  
  677. procedure SwapBytes(var A,B:byte);assembler;
  678. asm
  679.  push ds
  680.  les si,A
  681.  lds di,B
  682.  mov al,es:[si]
  683.  xchg al,[di]
  684.  mov es:[si],al
  685.  pop ds
  686. end;
  687.  
  688. procedure ClipPoint(var A1,B1:integer;A2,B2,L:integer);
  689. (* Applies the following formula for extending A1,B1 along *)
  690. (* a line such that B1=L                                   *)
  691. var
  692.  T0:longint;
  693.  T1,T2:integer;
  694. begin
  695.  T1:=A2-A1;
  696.  T2:=L-B1;
  697.  T0:=LongMul(T1,T2);
  698.  T1:=B2-B1;
  699.  if T1<>0 then
  700.    A1:=A1+LongDiv(T0,T1);
  701.  B1:=L;
  702. end;
  703.  
  704. function ClipLine(var X1,Y1,X2,Y2:integer;var R:TRect):boolean;
  705. var
  706.  Inside,Outside:boolean;
  707.  Ocu1,Ocu2:byte;
  708. begin
  709.  Ocu1:=RegionOf(X1,Y1,R.A.X,R.A.Y,R.B.X,R.B.Y);
  710.  Ocu2:=RegionOf(X2,Y2,R.A.X,R.A.Y,R.B.X,R.B.Y);
  711.  Inside:=((Ocu1 or Ocu2) = 0);
  712.  Outside:=((Ocu1 and Ocu2) <> 0);
  713.  
  714.  while not Inside and not Outside do
  715.  begin
  716.    if Ocu1=0 then
  717.    begin
  718.      SwapInts(X1,X2);
  719.      SwapInts(Y1,Y2);
  720.      SwapBytes(Ocu1,Ocu2);
  721.    end;
  722.  
  723.    if ((Ocu1 and $01)<>0) then
  724.      ClipPoint(Y1,X1,Y2,X2,R.A.X)
  725.    else if ((Ocu1 and $02)<>0) then
  726.      ClipPoint(X1,Y1,X2,Y2,R.A.Y)
  727.    else if ((Ocu1 and $04)<>0) then
  728.      ClipPoint(Y1,X1,Y2,X2,R.B.X)
  729.    else if ((Ocu1 and $08)<>0) then
  730.      ClipPoint(X1,Y1,X2,Y2,R.B.Y);
  731.  
  732.    Ocu1:=RegionOf(X1,Y1,R.A.X,R.A.Y,R.B.X,R.B.Y);
  733.    Ocu2:=RegionOf(X2,Y2,R.A.X,R.A.Y,R.B.X,R.B.Y);
  734.    Inside:=((Ocu1 or Ocu2) = 0);
  735.    Outside:=((Ocu1 and Ocu2) <> 0);
  736.  end;
  737.  ClipLine:=Inside;
  738. end;
  739.  
  740. procedure NoClipDrawLine(X1,Y1,X2,Y2:integer;Color:word);
  741. begin
  742.    if X1=X2 then
  743.       Draw_Vert_Line_X(X1,Y1,Y2,Color)
  744.    else if Y1=Y2 then
  745.       Draw_Horiz_Line_X(X1,X2,Y1,Color)
  746.    else Draw_Any_Line_X(X1,Y1,X2,Y2,Color);
  747. end;
  748.  
  749. procedure GlobalToPhysical(Var X,Y:integer);
  750. var
  751.  T:Longint;
  752. begin
  753.   T:=longmul(X,GraphWidth);
  754.   X:=longdiv(T,GraphXMax);
  755.   T:=longmul(Y,GraphHeight);
  756.   Y:=longdiv(T,GraphYMax);
  757. end;
  758.  
  759. procedure RawDrawLine(X1,Y1,X2,Y2:integer;Color:word);
  760. var
  761.  MR,R:TRect;
  762.  LineThruMouse:boolean;
  763.  X1M,X2M,Y1M,Y2M:integer;
  764.  (* MR is mouse rectangle, R is Window rectangle *)
  765. begin
  766.  R.Assign(0,0,GraphWidth-1,GraphHeight-1);
  767.  if ClipLine(X1,Y1,X2,Y2,R) then (* Line is visible *)
  768.  begin
  769.    with GraphMouseLoc do
  770.    begin
  771.      LineThruMouse:=(GraphIdAt(X-3,Y-3)=CurrentGraphWindow) or
  772.                     (GraphIdAt(X+16,Y-3)=CurrentGraphWindow) or
  773.                     (GraphIdAt(X-3,Y+16)=CurrentGraphWindow) or
  774.                     (GraphIdAt(X+16,Y+16)=CurrentGraphWindow);
  775.      MR.Assign(X-3,Y-3,X+16,Y+16);
  776.    end;
  777.    X1M:=X1;X2M:=X2;Y1M:=Y1;Y2M:=Y2;
  778.    if LineThruMouse then
  779.       LineThruMouse:=ClipLine(X1M,Y1M,X2M,Y2M,MR);
  780.  
  781.    if X1>X2 then
  782.    begin
  783.      SwapInts(X1,X2);
  784.      SwapInts(Y1,Y2);
  785.    end else if (X1=X2) and (Y1>Y2) then SwapInts(Y1,Y2);
  786.  
  787.    if LineThruMouse then
  788.      MouseCursorOff;
  789.    NoClipDrawLine(X1,Y1,X2,Y2,Color);
  790.    if LineThruMouse then
  791.      MouseCursorOn;
  792.  end;
  793. end;
  794.  
  795. procedure DrawLine(X1,Y1,X2,Y2:integer;Color:word);
  796. begin
  797.  GlobalToPhysical(X1,Y1);
  798.  GlobalToPhysical(X2,Y2);
  799.  RawDrawLine(X1,Y1,X2,Y2,Color);
  800. end;
  801.  
  802. procedure PhysicalToGlobal(Var P:GPoint);
  803. var
  804.  T:Longint;
  805. begin
  806.  with P do
  807.  begin
  808.    T:=longmul(X,GraphXMax);
  809.    X:=longdiv(T,GraphWidth);
  810.    T:=longmul(Y,GraphYMax);
  811.    Y:=longdiv(T,GraphHeight);
  812.  end;
  813. end;
  814.  
  815. procedure TextToGraphics(T:TRect;var G:GRect);
  816. begin
  817.  G.A.X:=T.A.X*CharWidth;
  818.  G.A.Y:=T.A.Y*CharHeight;
  819.  G.B.X:=T.B.X*CharWidth;
  820.  G.B.Y:=T.B.Y*CharHeight;
  821.  PhysicalToGlobal(GPoint(G.A));
  822.  PhysicalToGlobal(GPoint(G.B));
  823. end;
  824.  
  825. begin
  826.   (* overwrite the start of each of the main functions *)
  827.   P1:=@Drivers.InitVideo;
  828.   P2:=@NewJmp_InitVideo;
  829.   move(P2^,P1^,5);
  830.  
  831.   P1:=@Drivers.SetVideoMode;
  832.   P2:=@NewJmp_SetVideoMode;
  833.   move(P2^,P1^,5);
  834.  
  835.   P1:=@Drivers.DoneVideo;
  836.   P2:=@NewJmp_DoneVideo;
  837.   move(P2^,P1^,5);
  838.  
  839.   fillchar(graphidset,sizeof(graphidset),#0);
  840. end.
  841.  
  842.  
  843.  
  844.  
  845.